#include "StdAfx.h"
#include "ClientNetsystem.h"
#include "FileDB.h"
#include "ClientConnection.h"
#include <QApplication>
#include <QDir>

using namespace seven;

ClientNetsystem::ClientNetsystem(QObject *parent)
	: QObject(parent)
{
	state = NONE;
	tcpSocket = NULL;
}

ClientNetsystem::~ClientNetsystem()
{
	Clear();
}


void ClientNetsystem::Start()
{
	Clear();
	tcpSocket = new ClientConnection(this);
	connect(tcpSocket,SIGNAL(revMsg(const seven::TransferMessage& )),this,SLOT(HandleMsg(const seven::TransferMessage& )));
	SetState(START);
	fileDB = QSharedPointer<FileDB>(new FileDB());
}


void ClientNetsystem::OnPATH_TABLE_FINISHED(const seven::TransferMessage& msg )
{
	if (GetState()==PATH_TABLE_SENDING)
	{
		SetState(PATH_TABLE_FINISHED);
		if(SendFileTable(GetFileDB()))
		{
			SetState(FILE_TABLE_SENDING);
		}
	}
}

void ClientNetsystem::OnFILE_TABLE_FINISHED(const seven::TransferMessage& msg)
{
	if (GetState()==FILE_TABLE_SENDING)
	{
		SetState(FILE_TABLE_FINISHED);
	}
}

bool ClientNetsystem::SendPathTable(FileDB* pFileDB)
{
	if(!pFileDB)
	{
		return false;
	}

	seven::TransferMessage msg;
	msg.set_message_type(PATH_TABLE_REQ);
	pFileDB->GetPathTable(msg.mutable_path_table());
	SendTransferMsg(msg);

	return true;
}

bool ClientNetsystem::SendTransferMsg( seven::TransferMessage& msg )
{
	if(tcpSocket)
	{
		return tcpSocket->SendMsg(msg);
	}
	return false;
}

bool ClientNetsystem::SendFileTable( FileDB* pFileDB )
{
	if(!pFileDB)
	{
		return false;
	}

	seven::TransferMessage msg;
	msg.set_message_type(FILE_TABLE_REQ);
	FileTable * fileTable = msg.mutable_file_table();

	const FileDB::FileInfoTableType& fileInfoTable = pFileDB->GetFileInfoTable();
	for (int i = 0; i!=fileInfoTable.size(); ++i)
	{
		const FileDB::FileIntoItem& fileInfoItem = fileInfoTable[i];
		FileItem* item = fileTable->add_item();
		item->set_file_id(i);
		item->set_file_name(QString2String(fileInfoItem.filename));
		item->set_file_size(fileInfoItem.size);
		item->set_path_id(fileInfoItem.pathId);
	}

	SendTransferMsg(msg);

	return true;
}

void ClientNetsystem::OnCONNECTED(const seven::TransferMessage& msg )
{
	if (GetState()==CONNECT_PENDING)
	{
		SetState(CONNECTED);


		QString dstPath = QApplication::applicationDirPath() + "\\test";
		dstPath = QDir::toNativeSeparators(dstPath);
		fileDB->GenerateFileDB(dstPath);

		if (SendPathTable(GetFileDB()))
		{
			SetState(PATH_TABLE_SENDING);
		}
	}
}

void ClientNetsystem::Connect( const QString& host, const QString& port )
{
	if (tcpSocket)
	{
		tcpSocket->Connect(host,port);		
		SetState(CONNECT_PENDING);
	}
}

void ClientNetsystem::HandleMsg(const seven::TransferMessage& msg )
{
	switch(msg.message_type())
	{
	case PATH_TABLE_RSP:
		OnPATH_TABLE_FINISHED(msg);
		break;
	case FILE_TABLE_RSP:
		OnFILE_TABLE_FINISHED(msg);
		break;
	case ACCPET_CONNECT_RSP:
		OnCONNECTED(msg);
		break;
	case FILE_CONTENT_REQ:
		OnFILE_CONTENT_REQ(msg);
		break;
	default:
		Show("unhandle message!");
		break;
	}
}

void ClientNetsystem::OnFILE_CONTENT_REQ( const seven::TransferMessage& msg )
{
	if (!msg.has_file_content_req())
	{
		return;
	}

	int fileId = msg.file_content_req().file_id();
	QString fileName = fileDB->GetFilePath(fileId);

	QFile inFile(fileName); 
	if (!inFile.open(QIODevice::ReadOnly)) {
		QString error = inFile.errorString();
		QByteArray ba(error.toAscii());
		return ;
	}

	QDataStream binData;
	binData.setDevice(&inFile);

	int size = inFile.size();
	char* buff = new char[size];
	binData.readRawData(buff,size);

	seven::TransferMessage sendFileMsg;
	sendFileMsg.set_message_type(FILE_CONTENT_RSP);
	FileContentRsp* fileConetent = sendFileMsg.mutable_file_content_rsp();
	fileConetent->set_match(false);
	fileConetent->set_file_id(fileId);
	fileConetent->set_content(buff,size);
	SendTransferMsg(sendFileMsg);

	SAFE_DELETE(buff);
}

void ClientNetsystem::Clear()
{
	state = NONE;
	fileDB.clear();
	messageSize = 0;
	//if(tcpSocket)
	//{
	//	tcpSocket->Disconnect();
	//}
	SAFE_DELETE(tcpSocket);
}

